1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package javax.management.remote.rmi;
27
28 import com.sun.jmx.mbeanserver.Util;
29 import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
30 import com.sun.jmx.remote.internal.ClientListenerInfo;
31 import com.sun.jmx.remote.internal.ClientNotifForwarder;
32 import com.sun.jmx.remote.internal.ProxyRef;
33 import com.sun.jmx.remote.internal.IIOPHelper;
34 import com.sun.jmx.remote.util.ClassLogger;
35 import com.sun.jmx.remote.util.EnvHelp;
36 import java.io.ByteArrayInputStream;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.InvalidObjectException;
40 import java.io.NotSerializableException;
41 import java.io.ObjectInputStream;
42 import java.io.ObjectStreamClass;
43 import java.io.Serializable;
44 import java.io.WriteAbortedException;
45 import java.lang.ref.WeakReference;
46 import java.lang.reflect.Constructor;
47 import java.lang.reflect.InvocationHandler;
48 import java.lang.reflect.InvocationTargetException;
49 import java.lang.reflect.Proxy;
50 import java.net.MalformedURLException;
51 import java.rmi.MarshalException;
52 import java.rmi.MarshalledObject;
53 import java.rmi.NoSuchObjectException;
54 import java.rmi.Remote;
55 import java.rmi.ServerException;
56 import java.rmi.UnmarshalException;
57 import java.rmi.server.RMIClientSocketFactory;
58 import java.rmi.server.RemoteObject;
59 import java.rmi.server.RemoteObjectInvocationHandler;
60 import java.rmi.server.RemoteRef;
61 import java.security.AccessController;
62 import java.security.PrivilegedAction;
63 import java.security.PrivilegedExceptionAction;
64 import java.security.ProtectionDomain;
65 import java.util.Arrays;
66 import java.util.Collections;
67 import java.util.HashMap;
68 import java.util.Map;
69 import java.util.Properties;
70 import java.util.Set;
71 import java.util.WeakHashMap;
72 import javax.management.Attribute;
73 import javax.management.AttributeList;
74 import javax.management.AttributeNotFoundException;
75 import javax.management.InstanceAlreadyExistsException;
76 import javax.management.InstanceNotFoundException;
77 import javax.management.IntrospectionException;
78 import javax.management.InvalidAttributeValueException;
79 import javax.management.ListenerNotFoundException;
80 import javax.management.MBeanException;
81 import javax.management.MBeanInfo;
82 import javax.management.MBeanRegistrationException;
83 import javax.management.MBeanServerConnection;
84 import javax.management.MBeanServerDelegate;
85 import javax.management.MBeanServerNotification;
86 import javax.management.NotCompliantMBeanException;
87 import javax.management.Notification;
88 import javax.management.NotificationBroadcasterSupport;
89 import javax.management.NotificationFilter;
90 import javax.management.NotificationFilterSupport;
91 import javax.management.NotificationListener;
92 import javax.management.ObjectInstance;
93 import javax.management.ObjectName;
94 import javax.management.QueryExp;
95 import javax.management.ReflectionException;
96 import javax.management.remote.JMXConnectionNotification;
97 import javax.management.remote.JMXConnector;
98 import javax.management.remote.JMXConnectorFactory;
99 import javax.management.remote.JMXServiceURL;
100 import javax.management.remote.NotificationResult;
101 import javax.management.remote.JMXAddressable;
102 import javax.naming.InitialContext;
103 import javax.naming.NamingException;
104 import javax.rmi.ssl.SslRMIClientSocketFactory;
105 import javax.security.auth.Subject;
106 import sun.rmi.server.UnicastRef2;
107 import sun.rmi.transport.LiveRef;
108
109
110
111
112
113
114
115
116
117
118
119 public class RMIConnector implements JMXConnector, Serializable, JMXAddressable {
120
121 private static final ClassLogger logger =
122 new ClassLogger("javax.management.remote.rmi", "RMIConnector");
123
124 private static final long serialVersionUID = 817323035842634473L;
125
126 private RMIConnector(RMIServer rmiServer, JMXServiceURL address,
127 Map<String, ?> environment) {
128 if (rmiServer == null && address == null) throw new
129 IllegalArgumentException("rmiServer and jmxServiceURL both null");
130
131 initTransients();
132
133 this.rmiServer = rmiServer;
134 this.jmxServiceURL = address;
135 if (environment == null) {
136 this.env = Collections.emptyMap();
137 } else {
138 EnvHelp.checkAttributes(environment);
139 this.env = Collections.unmodifiableMap(environment);
140 }
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 public RMIConnector(JMXServiceURL url, Map<String,?> environment) {
185 this(null, url, environment);
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199 public RMIConnector(RMIServer rmiServer, Map<String,?> environment) {
200 this(rmiServer, null, environment);
201 }
202
203
204
205
206
207
208
209
210
211
212 @Override
213 public String toString() {
214 final StringBuilder b = new StringBuilder(this.getClass().getName());
215 b.append(":");
216 if (rmiServer != null) {
217 b.append(" rmiServer=").append(rmiServer.toString());
218 }
219 if (jmxServiceURL != null) {
220 if (rmiServer!=null) b.append(",");
221 b.append(" jmxServiceURL=").append(jmxServiceURL.toString());
222 }
223 return b.toString();
224 }
225
226
227
228
229
230
231
232
233
234 public JMXServiceURL getAddress() {
235 return jmxServiceURL;
236 }
237
238
239
240
241 public void connect() throws IOException {
242 connect(null);
243 }
244
245 public synchronized void connect(Map<String,?> environment)
246 throws IOException {
247 final boolean tracing = logger.traceOn();
248 String idstr = (tracing?"["+this.toString()+"]":null);
249
250 if (terminated) {
251 logger.trace("connect",idstr + " already closed.");
252 throw new IOException("Connector closed");
253 }
254 if (connected) {
255 logger.trace("connect",idstr + " already connected.");
256 return;
257 }
258
259 try {
260 if (tracing) logger.trace("connect",idstr + " connecting...");
261
262 final Map<String, Object> usemap =
263 new HashMap<String, Object>((this.env==null) ?
264 Collections.<String, Object>emptyMap() : this.env);
265
266
267 if (environment != null) {
268 EnvHelp.checkAttributes(environment);
269 usemap.putAll(environment);
270 }
271
272
273 if (tracing) logger.trace("connect",idstr + " finding stub...");
274 RMIServer stub = (rmiServer!=null)?rmiServer:
275 findRMIServer(jmxServiceURL, usemap);
276
277
278
279
280 boolean checkStub = EnvHelp.computeBooleanFromString(
281 usemap,
282 "jmx.remote.x.check.stub",false);
283 if (checkStub) checkStub(stub, rmiServerImplStubClass);
284
285
286 if (tracing) logger.trace("connect",idstr + " connecting stub...");
287 stub = connectStub(stub,usemap);
288 idstr = (tracing?"["+this.toString()+"]":null);
289
290
291 if (tracing)
292 logger.trace("connect",idstr + " getting connection...");
293 Object credentials = usemap.get(CREDENTIALS);
294
295 try {
296 connection = getConnection(stub, credentials, checkStub);
297 } catch (java.rmi.RemoteException re) {
298 if (jmxServiceURL != null) {
299 final String pro = jmxServiceURL.getProtocol();
300 final String path = jmxServiceURL.getURLPath();
301
302 if ("rmi".equals(pro) &&
303 path.startsWith("/jndi/iiop:")) {
304 MalformedURLException mfe = new MalformedURLException(
305 "Protocol is rmi but JNDI scheme is iiop: " + jmxServiceURL);
306 mfe.initCause(re);
307 throw mfe;
308 }
309 }
310 throw re;
311 }
312
313
314
315
316 if (tracing)
317 logger.trace("connect",idstr + " getting class loader...");
318 defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap);
319
320 usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,
321 defaultClassLoader);
322
323 rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap);
324
325 env = usemap;
326 final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap);
327 communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod);
328
329 connected = true;
330
331
332
333
334 connectionId = getConnectionId();
335
336 Notification connectedNotif =
337 new JMXConnectionNotification(JMXConnectionNotification.OPENED,
338 this,
339 connectionId,
340 clientNotifSeqNo++,
341 "Successful connection",
342 null);
343 sendNotification(connectedNotif);
344
345 if (tracing) logger.trace("connect",idstr + " done...");
346 } catch (IOException e) {
347 if (tracing)
348 logger.trace("connect",idstr + " failed to connect: " + e);
349 throw e;
350 } catch (RuntimeException e) {
351 if (tracing)
352 logger.trace("connect",idstr + " failed to connect: " + e);
353 throw e;
354 } catch (NamingException e) {
355 final String msg = "Failed to retrieve RMIServer stub: " + e;
356 if (tracing) logger.trace("connect",idstr + " " + msg);
357 throw EnvHelp.initCause(new IOException(msg),e);
358 }
359 }
360
361 public synchronized String getConnectionId() throws IOException {
362 if (terminated || !connected) {
363 if (logger.traceOn())
364 logger.trace("getConnectionId","["+this.toString()+
365 "] not connected.");
366
367 throw new IOException("Not connected");
368 }
369
370
371
372 return connection.getConnectionId();
373 }
374
375 public synchronized MBeanServerConnection getMBeanServerConnection()
376 throws IOException {
377 return getMBeanServerConnection(null);
378 }
379
380 public synchronized MBeanServerConnection
381 getMBeanServerConnection(Subject delegationSubject)
382 throws IOException {
383
384 if (terminated) {
385 if (logger.traceOn())
386 logger.trace("getMBeanServerConnection","[" + this.toString() +
387 "] already closed.");
388 throw new IOException("Connection closed");
389 } else if (!connected) {
390 if (logger.traceOn())
391 logger.trace("getMBeanServerConnection","[" + this.toString() +
392 "] is not connected.");
393 throw new IOException("Not connected");
394 }
395
396 MBeanServerConnection rmbsc = rmbscMap.get(delegationSubject);
397 if (rmbsc != null) {
398 return rmbsc;
399 }
400
401 rmbsc = new RemoteMBeanServerConnection(delegationSubject);
402 rmbscMap.put(delegationSubject, rmbsc);
403 return rmbsc;
404 }
405
406 public void
407 addConnectionNotificationListener(NotificationListener listener,
408 NotificationFilter filter,
409 Object handback) {
410 if (listener == null)
411 throw new NullPointerException("listener");
412 connectionBroadcaster.addNotificationListener(listener, filter,
413 handback);
414 }
415
416 public void
417 removeConnectionNotificationListener(NotificationListener listener)
418 throws ListenerNotFoundException {
419 if (listener == null)
420 throw new NullPointerException("listener");
421 connectionBroadcaster.removeNotificationListener(listener);
422 }
423
424 public void
425 removeConnectionNotificationListener(NotificationListener listener,
426 NotificationFilter filter,
427 Object handback)
428 throws ListenerNotFoundException {
429 if (listener == null)
430 throw new NullPointerException("listener");
431 connectionBroadcaster.removeNotificationListener(listener, filter,
432 handback);
433 }
434
435 private void sendNotification(Notification n) {
436 connectionBroadcaster.sendNotification(n);
437 }
438
439 public synchronized void close() throws IOException {
440 close(false);
441 }
442
443
444
445 private synchronized void close(boolean intern) throws IOException {
446 final boolean tracing = logger.traceOn();
447 final boolean debug = logger.debugOn();
448 final String idstr = (tracing?"["+this.toString()+"]":null);
449
450 if (!intern) {
451
452
453 if (terminated) {
454 if (closeException == null) {
455 if (tracing) logger.trace("close",idstr + " already closed.");
456 return;
457 }
458 } else {
459 terminated = true;
460 }
461 }
462
463 if (closeException != null && tracing) {
464
465
466 if (tracing) {
467 logger.trace("close",idstr + " had failed: " + closeException);
468 logger.trace("close",idstr + " attempting to close again.");
469 }
470 }
471
472 String savedConnectionId = null;
473 if (connected) {
474 savedConnectionId = connectionId;
475 }
476
477 closeException = null;
478
479 if (tracing) logger.trace("close",idstr + " closing.");
480
481 if (communicatorAdmin != null) {
482 communicatorAdmin.terminate();
483 }
484
485 if (rmiNotifClient != null) {
486 try {
487 rmiNotifClient.terminate();
488 if (tracing) logger.trace("close",idstr +
489 " RMI Notification client terminated.");
490 } catch (RuntimeException x) {
491 closeException = x;
492 if (tracing) logger.trace("close",idstr +
493 " Failed to terminate RMI Notification client: " + x);
494 if (debug) logger.debug("close",x);
495 }
496 }
497
498 if (connection != null) {
499 try {
500 connection.close();
501 if (tracing) logger.trace("close",idstr + " closed.");
502 } catch (NoSuchObjectException nse) {
503
504 } catch (IOException e) {
505 closeException = e;
506 if (tracing) logger.trace("close",idstr +
507 " Failed to close RMIServer: " + e);
508 if (debug) logger.debug("close",e);
509 }
510 }
511
512
513
514 rmbscMap.clear();
515
516
517
518
519
520 if (savedConnectionId != null) {
521 Notification closedNotif =
522 new JMXConnectionNotification(JMXConnectionNotification.CLOSED,
523 this,
524 savedConnectionId,
525 clientNotifSeqNo++,
526 "Client has been closed",
527 null);
528 sendNotification(closedNotif);
529 }
530
531
532
533 if (closeException != null) {
534 if (tracing) logger.trace("close",idstr + " failed to close: " +
535 closeException);
536 if (closeException instanceof IOException)
537 throw (IOException) closeException;
538 if (closeException instanceof RuntimeException)
539 throw (RuntimeException) closeException;
540 final IOException x =
541 new IOException("Failed to close: " + closeException);
542 throw EnvHelp.initCause(x,closeException);
543 }
544 }
545
546
547 private Integer addListenerWithSubject(ObjectName name,
548 MarshalledObject<NotificationFilter> filter,
549 Subject delegationSubject,
550 boolean reconnect)
551 throws InstanceNotFoundException, IOException {
552
553 final boolean debug = logger.debugOn();
554 if (debug)
555 logger.debug("addListenerWithSubject",
556 "(ObjectName,MarshalledObject,Subject)");
557
558 final ObjectName[] names = new ObjectName[] {name};
559 final MarshalledObject<NotificationFilter>[] filters =
560 Util.cast(new MarshalledObject<?>[] {filter});
561 final Subject[] delegationSubjects = new Subject[] {
562 delegationSubject
563 };
564
565 final Integer[] listenerIDs =
566 addListenersWithSubjects(names,filters,delegationSubjects,
567 reconnect);
568
569 if (debug) logger.debug("addListenerWithSubject","listenerID="
570 + listenerIDs[0]);
571 return listenerIDs[0];
572 }
573
574
575 private Integer[] addListenersWithSubjects(ObjectName[] names,
576 MarshalledObject<NotificationFilter>[] filters,
577 Subject[] delegationSubjects,
578 boolean reconnect)
579 throws InstanceNotFoundException, IOException {
580
581 final boolean debug = logger.debugOn();
582 if (debug)
583 logger.debug("addListenersWithSubjects",
584 "(ObjectName[],MarshalledObject[],Subject[])");
585
586 final ClassLoader old = pushDefaultClassLoader();
587 Integer[] listenerIDs = null;
588
589 try {
590 listenerIDs = connection.addNotificationListeners(names,
591 filters,
592 delegationSubjects);
593 } catch (NoSuchObjectException noe) {
594
595 if (reconnect) {
596 communicatorAdmin.gotIOException(noe);
597
598 listenerIDs = connection.addNotificationListeners(names,
599 filters,
600 delegationSubjects);
601 } else {
602 throw noe;
603 }
604 } catch (IOException ioe) {
605
606 communicatorAdmin.gotIOException(ioe);
607 } finally {
608 popDefaultClassLoader(old);
609 }
610
611 if (debug) logger.debug("addListenersWithSubjects","registered "
612 + ((listenerIDs==null)?0:listenerIDs.length)
613 + " listener(s)");
614 return listenerIDs;
615 }
616
617
618
619
620 private class RemoteMBeanServerConnection implements MBeanServerConnection {
621 private Subject delegationSubject;
622
623 public RemoteMBeanServerConnection() {
624 this(null);
625 }
626
627 public RemoteMBeanServerConnection(Subject delegationSubject) {
628 this.delegationSubject = delegationSubject;
629 }
630
631 public ObjectInstance createMBean(String className,
632 ObjectName name)
633 throws ReflectionException,
634 InstanceAlreadyExistsException,
635 MBeanRegistrationException,
636 MBeanException,
637 NotCompliantMBeanException,
638 IOException {
639 if (logger.debugOn())
640 logger.debug("createMBean(String,ObjectName)",
641 "className=" + className + ", name=" +
642 name);
643
644 final ClassLoader old = pushDefaultClassLoader();
645 try {
646 return connection.createMBean(className,
647 name,
648 delegationSubject);
649 } catch (IOException ioe) {
650 communicatorAdmin.gotIOException(ioe);
651
652 return connection.createMBean(className,
653 name,
654 delegationSubject);
655 } finally {
656 popDefaultClassLoader(old);
657 }
658 }
659
660 public ObjectInstance createMBean(String className,
661 ObjectName name,
662 ObjectName loaderName)
663 throws ReflectionException,
664 InstanceAlreadyExistsException,
665 MBeanRegistrationException,
666 MBeanException,
667 NotCompliantMBeanException,
668 InstanceNotFoundException,
669 IOException {
670
671 if (logger.debugOn())
672 logger.debug("createMBean(String,ObjectName,ObjectName)",
673 "className=" + className + ", name="
674 + name + ", loaderName="
675 + loaderName + ")");
676
677 final ClassLoader old = pushDefaultClassLoader();
678 try {
679 return connection.createMBean(className,
680 name,
681 loaderName,
682 delegationSubject);
683
684 } catch (IOException ioe) {
685 communicatorAdmin.gotIOException(ioe);
686
687 return connection.createMBean(className,
688 name,
689 loaderName,
690 delegationSubject);
691
692 } finally {
693 popDefaultClassLoader(old);
694 }
695 }
696
697 public ObjectInstance createMBean(String className,
698 ObjectName name,
699 Object params[],
700 String signature[])
701 throws ReflectionException,
702 InstanceAlreadyExistsException,
703 MBeanRegistrationException,
704 MBeanException,
705 NotCompliantMBeanException,
706 IOException {
707 if (logger.debugOn())
708 logger.debug("createMBean(String,ObjectName,Object[],String[])",
709 "className=" + className + ", name="
710 + name + ", params="
711 + objects(params) + ", signature="
712 + strings(signature));
713
714 final MarshalledObject<Object[]> sParams =
715 new MarshalledObject<Object[]>(params);
716 final ClassLoader old = pushDefaultClassLoader();
717 try {
718 return connection.createMBean(className,
719 name,
720 sParams,
721 signature,
722 delegationSubject);
723 } catch (IOException ioe) {
724 communicatorAdmin.gotIOException(ioe);
725
726 return connection.createMBean(className,
727 name,
728 sParams,
729 signature,
730 delegationSubject);
731 } finally {
732 popDefaultClassLoader(old);
733 }
734 }
735
736 public ObjectInstance createMBean(String className,
737 ObjectName name,
738 ObjectName loaderName,
739 Object params[],
740 String signature[])
741 throws ReflectionException,
742 InstanceAlreadyExistsException,
743 MBeanRegistrationException,
744 MBeanException,
745 NotCompliantMBeanException,
746 InstanceNotFoundException,
747 IOException {
748 if (logger.debugOn()) logger.debug(
749 "createMBean(String,ObjectName,ObjectName,Object[],String[])",
750 "className=" + className + ", name=" + name + ", loaderName="
751 + loaderName + ", params=" + objects(params)
752 + ", signature=" + strings(signature));
753
754 final MarshalledObject<Object[]> sParams =
755 new MarshalledObject<Object[]>(params);
756 final ClassLoader old = pushDefaultClassLoader();
757 try {
758 return connection.createMBean(className,
759 name,
760 loaderName,
761 sParams,
762 signature,
763 delegationSubject);
764 } catch (IOException ioe) {
765 communicatorAdmin.gotIOException(ioe);
766
767 return connection.createMBean(className,
768 name,
769 loaderName,
770 sParams,
771 signature,
772 delegationSubject);
773 } finally {
774 popDefaultClassLoader(old);
775 }
776 }
777
778 public void unregisterMBean(ObjectName name)
779 throws InstanceNotFoundException,
780 MBeanRegistrationException,
781 IOException {
782 if (logger.debugOn())
783 logger.debug("unregisterMBean", "name=" + name);
784
785 final ClassLoader old = pushDefaultClassLoader();
786 try {
787 connection.unregisterMBean(name, delegationSubject);
788 } catch (IOException ioe) {
789 communicatorAdmin.gotIOException(ioe);
790
791 connection.unregisterMBean(name, delegationSubject);
792 } finally {
793 popDefaultClassLoader(old);
794 }
795 }
796
797 public ObjectInstance getObjectInstance(ObjectName name)
798 throws InstanceNotFoundException,
799 IOException {
800 if (logger.debugOn())
801 logger.debug("getObjectInstance", "name=" + name);
802
803 final ClassLoader old = pushDefaultClassLoader();
804 try {
805 return connection.getObjectInstance(name, delegationSubject);
806 } catch (IOException ioe) {
807 communicatorAdmin.gotIOException(ioe);
808
809 return connection.getObjectInstance(name, delegationSubject);
810 } finally {
811 popDefaultClassLoader(old);
812 }
813 }
814
815 public Set<ObjectInstance> queryMBeans(ObjectName name,
816 QueryExp query)
817 throws IOException {
818 if (logger.debugOn()) logger.debug("queryMBeans",
819 "name=" + name + ", query=" + query);
820
821 final MarshalledObject<QueryExp> sQuery =
822 new MarshalledObject<QueryExp>(query);
823 final ClassLoader old = pushDefaultClassLoader();
824 try {
825 return connection.queryMBeans(name, sQuery, delegationSubject);
826 } catch (IOException ioe) {
827 communicatorAdmin.gotIOException(ioe);
828
829 return connection.queryMBeans(name, sQuery, delegationSubject);
830 } finally {
831 popDefaultClassLoader(old);
832 }
833 }
834
835 public Set<ObjectName> queryNames(ObjectName name,
836 QueryExp query)
837 throws IOException {
838 if (logger.debugOn()) logger.debug("queryNames",
839 "name=" + name + ", query=" + query);
840
841 final MarshalledObject<QueryExp> sQuery =
842 new MarshalledObject<QueryExp>(query);
843 final ClassLoader old = pushDefaultClassLoader();
844 try {
845 return connection.queryNames(name, sQuery, delegationSubject);
846 } catch (IOException ioe) {
847 communicatorAdmin.gotIOException(ioe);
848
849 return connection.queryNames(name, sQuery, delegationSubject);
850 } finally {
851 popDefaultClassLoader(old);
852 }
853 }
854
855 public boolean isRegistered(ObjectName name)
856 throws IOException {
857 if (logger.debugOn())
858 logger.debug("isRegistered", "name=" + name);
859
860 final ClassLoader old = pushDefaultClassLoader();
861 try {
862 return connection.isRegistered(name, delegationSubject);
863 } catch (IOException ioe) {
864 communicatorAdmin.gotIOException(ioe);
865
866 return connection.isRegistered(name, delegationSubject);
867 } finally {
868 popDefaultClassLoader(old);
869 }
870 }
871
872 public Integer getMBeanCount()
873 throws IOException {
874 if (logger.debugOn()) logger.debug("getMBeanCount", "");
875
876 final ClassLoader old = pushDefaultClassLoader();
877 try {
878 return connection.getMBeanCount(delegationSubject);
879 } catch (IOException ioe) {
880 communicatorAdmin.gotIOException(ioe);
881
882 return connection.getMBeanCount(delegationSubject);
883 } finally {
884 popDefaultClassLoader(old);
885 }
886 }
887
888 public Object getAttribute(ObjectName name,
889 String attribute)
890 throws MBeanException,
891 AttributeNotFoundException,
892 InstanceNotFoundException,
893 ReflectionException,
894 IOException {
895 if (logger.debugOn()) logger.debug("getAttribute",
896 "name=" + name + ", attribute="
897 + attribute);
898
899 final ClassLoader old = pushDefaultClassLoader();
900 try {
901 return connection.getAttribute(name,
902 attribute,
903 delegationSubject);
904 } catch (IOException ioe) {
905 communicatorAdmin.gotIOException(ioe);
906
907 return connection.getAttribute(name,
908 attribute,
909 delegationSubject);
910 } finally {
911 popDefaultClassLoader(old);
912 }
913 }
914
915 public AttributeList getAttributes(ObjectName name,
916 String[] attributes)
917 throws InstanceNotFoundException,
918 ReflectionException,
919 IOException {
920 if (logger.debugOn()) logger.debug("getAttributes",
921 "name=" + name + ", attributes="
922 + strings(attributes));
923
924 final ClassLoader old = pushDefaultClassLoader();
925 try {
926 return connection.getAttributes(name,
927 attributes,
928 delegationSubject);
929
930 } catch (IOException ioe) {
931 communicatorAdmin.gotIOException(ioe);
932
933 return connection.getAttributes(name,
934 attributes,
935 delegationSubject);
936 } finally {
937 popDefaultClassLoader(old);
938 }
939 }
940
941
942 public void setAttribute(ObjectName name,
943 Attribute attribute)
944 throws InstanceNotFoundException,
945 AttributeNotFoundException,
946 InvalidAttributeValueException,
947 MBeanException,
948 ReflectionException,
949 IOException {
950
951 if (logger.debugOn()) logger.debug("setAttribute",
952 "name=" + name + ", attribute="
953 + attribute);
954
955 final MarshalledObject<Attribute> sAttribute =
956 new MarshalledObject<Attribute>(attribute);
957 final ClassLoader old = pushDefaultClassLoader();
958 try {
959 connection.setAttribute(name, sAttribute, delegationSubject);
960 } catch (IOException ioe) {
961 communicatorAdmin.gotIOException(ioe);
962
963 connection.setAttribute(name, sAttribute, delegationSubject);
964 } finally {
965 popDefaultClassLoader(old);
966 }
967 }
968
969 public AttributeList setAttributes(ObjectName name,
970 AttributeList attributes)
971 throws InstanceNotFoundException,
972 ReflectionException,
973 IOException {
974
975 if (logger.debugOn()) logger.debug("setAttributes",
976 "name=" + name + ", attributes="
977 + attributes);
978
979 final MarshalledObject<AttributeList> sAttributes =
980 new MarshalledObject<AttributeList>(attributes);
981 final ClassLoader old = pushDefaultClassLoader();
982 try {
983 return connection.setAttributes(name,
984 sAttributes,
985 delegationSubject);
986 } catch (IOException ioe) {
987 communicatorAdmin.gotIOException(ioe);
988
989 return connection.setAttributes(name,
990 sAttributes,
991 delegationSubject);
992 } finally {
993 popDefaultClassLoader(old);
994 }
995 }
996
997
998 public Object invoke(ObjectName name,
999 String operationName,
1000 Object params[],
1001 String signature[])
1002 throws InstanceNotFoundException,
1003 MBeanException,
1004 ReflectionException,
1005 IOException {
1006
1007 if (logger.debugOn()) logger.debug("invoke",
1008 "name=" + name
1009 + ", operationName=" + operationName
1010 + ", params=" + objects(params)
1011 + ", signature=" + strings(signature));
1012
1013 final MarshalledObject<Object[]> sParams =
1014 new MarshalledObject<Object[]>(params);
1015 final ClassLoader old = pushDefaultClassLoader();
1016 try {
1017 return connection.invoke(name,
1018 operationName,
1019 sParams,
1020 signature,
1021 delegationSubject);
1022 } catch (IOException ioe) {
1023 communicatorAdmin.gotIOException(ioe);
1024
1025 return connection.invoke(name,
1026 operationName,
1027 sParams,
1028 signature,
1029 delegationSubject);
1030 } finally {
1031 popDefaultClassLoader(old);
1032 }
1033 }
1034
1035
1036 public String getDefaultDomain()
1037 throws IOException {
1038 if (logger.debugOn()) logger.debug("getDefaultDomain", "");
1039
1040 final ClassLoader old = pushDefaultClassLoader();
1041 try {
1042 return connection.getDefaultDomain(delegationSubject);
1043 } catch (IOException ioe) {
1044 communicatorAdmin.gotIOException(ioe);
1045
1046 return connection.getDefaultDomain(delegationSubject);
1047 } finally {
1048 popDefaultClassLoader(old);
1049 }
1050 }
1051
1052 public String[] getDomains() throws IOException {
1053 if (logger.debugOn()) logger.debug("getDomains", "");
1054
1055 final ClassLoader old = pushDefaultClassLoader();
1056 try {
1057 return connection.getDomains(delegationSubject);
1058 } catch (IOException ioe) {
1059 communicatorAdmin.gotIOException(ioe);
1060
1061 return connection.getDomains(delegationSubject);
1062 } finally {
1063 popDefaultClassLoader(old);
1064 }
1065 }
1066
1067 public MBeanInfo getMBeanInfo(ObjectName name)
1068 throws InstanceNotFoundException,
1069 IntrospectionException,
1070 ReflectionException,
1071 IOException {
1072
1073 if (logger.debugOn()) logger.debug("getMBeanInfo", "name=" + name);
1074 final ClassLoader old = pushDefaultClassLoader();
1075 try {
1076 return connection.getMBeanInfo(name, delegationSubject);
1077 } catch (IOException ioe) {
1078 communicatorAdmin.gotIOException(ioe);
1079
1080 return connection.getMBeanInfo(name, delegationSubject);
1081 } finally {
1082 popDefaultClassLoader(old);
1083 }
1084 }
1085
1086
1087 public boolean isInstanceOf(ObjectName name,
1088 String className)
1089 throws InstanceNotFoundException,
1090 IOException {
1091 if (logger.debugOn())
1092 logger.debug("isInstanceOf", "name=" + name +
1093 ", className=" + className);
1094
1095 final ClassLoader old = pushDefaultClassLoader();
1096 try {
1097 return connection.isInstanceOf(name,
1098 className,
1099 delegationSubject);
1100 } catch (IOException ioe) {
1101 communicatorAdmin.gotIOException(ioe);
1102
1103 return connection.isInstanceOf(name,
1104 className,
1105 delegationSubject);
1106 } finally {
1107 popDefaultClassLoader(old);
1108 }
1109 }
1110
1111 public void addNotificationListener(ObjectName name,
1112 ObjectName listener,
1113 NotificationFilter filter,
1114 Object handback)
1115 throws InstanceNotFoundException,
1116 IOException {
1117
1118 if (logger.debugOn())
1119 logger.debug("addNotificationListener" +
1120 "(ObjectName,ObjectName,NotificationFilter,Object)",
1121 "name=" + name + ", listener=" + listener
1122 + ", filter=" + filter + ", handback=" + handback);
1123
1124 final MarshalledObject<NotificationFilter> sFilter =
1125 new MarshalledObject<NotificationFilter>(filter);
1126 final MarshalledObject<Object> sHandback =
1127 new MarshalledObject<Object>(handback);
1128 final ClassLoader old = pushDefaultClassLoader();
1129 try {
1130 connection.addNotificationListener(name,
1131 listener,
1132 sFilter,
1133 sHandback,
1134 delegationSubject);
1135 } catch (IOException ioe) {
1136 communicatorAdmin.gotIOException(ioe);
1137
1138 connection.addNotificationListener(name,
1139 listener,
1140 sFilter,
1141 sHandback,
1142 delegationSubject);
1143 } finally {
1144 popDefaultClassLoader(old);
1145 }
1146 }
1147
1148 public void removeNotificationListener(ObjectName name,
1149 ObjectName listener)
1150 throws InstanceNotFoundException,
1151 ListenerNotFoundException,
1152 IOException {
1153
1154 if (logger.debugOn()) logger.debug("removeNotificationListener" +
1155 "(ObjectName,ObjectName)",
1156 "name=" + name
1157 + ", listener=" + listener);
1158
1159 final ClassLoader old = pushDefaultClassLoader();
1160 try {
1161 connection.removeNotificationListener(name,
1162 listener,
1163 delegationSubject);
1164 } catch (IOException ioe) {
1165 communicatorAdmin.gotIOException(ioe);
1166
1167 connection.removeNotificationListener(name,
1168 listener,
1169 delegationSubject);
1170 } finally {
1171 popDefaultClassLoader(old);
1172 }
1173 }
1174
1175 public void removeNotificationListener(ObjectName name,
1176 ObjectName listener,
1177 NotificationFilter filter,
1178 Object handback)
1179 throws InstanceNotFoundException,
1180 ListenerNotFoundException,
1181 IOException {
1182 if (logger.debugOn())
1183 logger.debug("removeNotificationListener" +
1184 "(ObjectName,ObjectName,NotificationFilter,Object)",
1185 "name=" + name
1186 + ", listener=" + listener
1187 + ", filter=" + filter
1188 + ", handback=" + handback);
1189
1190 final MarshalledObject<NotificationFilter> sFilter =
1191 new MarshalledObject<NotificationFilter>(filter);
1192 final MarshalledObject<Object> sHandback =
1193 new MarshalledObject<Object>(handback);
1194 final ClassLoader old = pushDefaultClassLoader();
1195 try {
1196 connection.removeNotificationListener(name,
1197 listener,
1198 sFilter,
1199 sHandback,
1200 delegationSubject);
1201 } catch (IOException ioe) {
1202 communicatorAdmin.gotIOException(ioe);
1203
1204 connection.removeNotificationListener(name,
1205 listener,
1206 sFilter,
1207 sHandback,
1208 delegationSubject);
1209 } finally {
1210 popDefaultClassLoader(old);
1211 }
1212 }
1213
1214
1215
1216 public void addNotificationListener(ObjectName name,
1217 NotificationListener listener,
1218 NotificationFilter filter,
1219 Object handback)
1220 throws InstanceNotFoundException,
1221 IOException {
1222
1223 final boolean debug = logger.debugOn();
1224
1225 if (debug)
1226 logger.debug("addNotificationListener" +
1227 "(ObjectName,NotificationListener,"+
1228 "NotificationFilter,Object)",
1229 "name=" + name
1230 + ", listener=" + listener
1231 + ", filter=" + filter
1232 + ", handback=" + handback);
1233
1234 final Integer listenerID =
1235 addListenerWithSubject(name,
1236 new MarshalledObject<NotificationFilter>(filter),
1237 delegationSubject,true);
1238 rmiNotifClient.addNotificationListener(listenerID, name, listener,
1239 filter, handback,
1240 delegationSubject);
1241 }
1242
1243 public void removeNotificationListener(ObjectName name,
1244 NotificationListener listener)
1245 throws InstanceNotFoundException,
1246 ListenerNotFoundException,
1247 IOException {
1248
1249 final boolean debug = logger.debugOn();
1250
1251 if (debug) logger.debug("removeNotificationListener"+
1252 "(ObjectName,NotificationListener)",
1253 "name=" + name
1254 + ", listener=" + listener);
1255
1256 final Integer[] ret =
1257 rmiNotifClient.removeNotificationListener(name, listener);
1258
1259 if (debug) logger.debug("removeNotificationListener",
1260 "listenerIDs=" + objects(ret));
1261
1262 final ClassLoader old = pushDefaultClassLoader();
1263
1264 try {
1265 connection.removeNotificationListeners(name,
1266 ret,
1267 delegationSubject);
1268 } catch (IOException ioe) {
1269 communicatorAdmin.gotIOException(ioe);
1270
1271 connection.removeNotificationListeners(name,
1272 ret,
1273 delegationSubject);
1274 } finally {
1275 popDefaultClassLoader(old);
1276 }
1277
1278 }
1279
1280 public void removeNotificationListener(ObjectName name,
1281 NotificationListener listener,
1282 NotificationFilter filter,
1283 Object handback)
1284 throws InstanceNotFoundException,
1285 ListenerNotFoundException,
1286 IOException {
1287 final boolean debug = logger.debugOn();
1288
1289 if (debug)
1290 logger.debug("removeNotificationListener"+
1291 "(ObjectName,NotificationListener,"+
1292 "NotificationFilter,Object)",
1293 "name=" + name
1294 + ", listener=" + listener
1295 + ", filter=" + filter
1296 + ", handback=" + handback);
1297
1298 final Integer ret =
1299 rmiNotifClient.removeNotificationListener(name, listener,
1300 filter, handback);
1301
1302 if (debug) logger.debug("removeNotificationListener",
1303 "listenerID=" + ret);
1304
1305 final ClassLoader old = pushDefaultClassLoader();
1306 try {
1307 connection.removeNotificationListeners(name,
1308 new Integer[] {ret},
1309 delegationSubject);
1310 } catch (IOException ioe) {
1311 communicatorAdmin.gotIOException(ioe);
1312
1313 connection.removeNotificationListeners(name,
1314 new Integer[] {ret},
1315 delegationSubject);
1316 } finally {
1317 popDefaultClassLoader(old);
1318 }
1319
1320 }
1321 }
1322
1323
1324 private class RMINotifClient extends ClientNotifForwarder {
1325 public RMINotifClient(ClassLoader cl, Map<String, ?> env) {
1326 super(cl, env);
1327 }
1328
1329 protected NotificationResult fetchNotifs(long clientSequenceNumber,
1330 int maxNotifications,
1331 long timeout)
1332 throws IOException, ClassNotFoundException {
1333 IOException org;
1334
1335 while (true) {
1336 try {
1337 return connection.fetchNotifications(clientSequenceNumber,
1338 maxNotifications,
1339 timeout);
1340 } catch (IOException ioe) {
1341 org = ioe;
1342
1343
1344 try {
1345 communicatorAdmin.gotIOException(ioe);
1346
1347
1348 continue;
1349 } catch (IOException ee) {
1350
1351 break;
1352 }
1353 }
1354 }
1355
1356
1357 if (org instanceof UnmarshalException) {
1358 UnmarshalException ume = (UnmarshalException)org;
1359
1360 if (ume.detail instanceof ClassNotFoundException)
1361 throw (ClassNotFoundException) ume.detail;
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 if (ume.detail instanceof WriteAbortedException) {
1377 WriteAbortedException wae =
1378 (WriteAbortedException) ume.detail;
1379 if (wae.detail instanceof IOException)
1380 throw (IOException) wae.detail;
1381 }
1382 } else if (org instanceof MarshalException) {
1383
1384
1385 MarshalException me = (MarshalException)org;
1386 if (me.detail instanceof NotSerializableException) {
1387 throw (NotSerializableException)me.detail;
1388 }
1389 }
1390
1391
1392 throw org;
1393 }
1394
1395 protected Integer addListenerForMBeanRemovedNotif()
1396 throws IOException, InstanceNotFoundException {
1397 NotificationFilterSupport clientFilter =
1398 new NotificationFilterSupport();
1399 clientFilter.enableType(
1400 MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
1401 MarshalledObject<NotificationFilter> sFilter =
1402 new MarshalledObject<NotificationFilter>(clientFilter);
1403
1404 Integer[] listenerIDs;
1405 final ObjectName[] names =
1406 new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME};
1407 final MarshalledObject<NotificationFilter>[] filters =
1408 Util.cast(new MarshalledObject<?>[] {sFilter});
1409 final Subject[] subjects = new Subject[] {null};
1410 try {
1411 listenerIDs =
1412 connection.addNotificationListeners(names,
1413 filters,
1414 subjects);
1415
1416 } catch (IOException ioe) {
1417 communicatorAdmin.gotIOException(ioe);
1418
1419 listenerIDs =
1420 connection.addNotificationListeners(names,
1421 filters,
1422 subjects);
1423 }
1424 return listenerIDs[0];
1425 }
1426
1427 protected void removeListenerForMBeanRemovedNotif(Integer id)
1428 throws IOException, InstanceNotFoundException,
1429 ListenerNotFoundException {
1430 try {
1431 connection.removeNotificationListeners(
1432 MBeanServerDelegate.DELEGATE_NAME,
1433 new Integer[] {id},
1434 null);
1435 } catch (IOException ioe) {
1436 communicatorAdmin.gotIOException(ioe);
1437
1438 connection.removeNotificationListeners(
1439 MBeanServerDelegate.DELEGATE_NAME,
1440 new Integer[] {id},
1441 null);
1442 }
1443
1444 }
1445
1446 protected void lostNotifs(String message, long number) {
1447 final String notifType = JMXConnectionNotification.NOTIFS_LOST;
1448
1449 final JMXConnectionNotification n =
1450 new JMXConnectionNotification(notifType,
1451 RMIConnector.this,
1452 connectionId,
1453 clientNotifCounter++,
1454 message,
1455 Long.valueOf(number));
1456 sendNotification(n);
1457 }
1458 }
1459
1460 private class RMIClientCommunicatorAdmin extends ClientCommunicatorAdmin {
1461 public RMIClientCommunicatorAdmin(long period) {
1462 super(period);
1463 }
1464
1465 @Override
1466 public void gotIOException(IOException ioe) throws IOException {
1467 if (ioe instanceof NoSuchObjectException) {
1468
1469 super.gotIOException(ioe);
1470
1471 return;
1472 }
1473
1474
1475 try {
1476 connection.getDefaultDomain(null);
1477 } catch (IOException ioexc) {
1478 boolean toClose = false;
1479
1480 synchronized(this) {
1481 if (!terminated) {
1482 terminated = true;
1483
1484 toClose = true;
1485 }
1486 }
1487
1488 if (toClose) {
1489
1490
1491 final Notification failedNotif =
1492 new JMXConnectionNotification(
1493 JMXConnectionNotification.FAILED,
1494 this,
1495 connectionId,
1496 clientNotifSeqNo++,
1497 "Failed to communicate with the server: "+ioe.toString(),
1498 ioe);
1499
1500 sendNotification(failedNotif);
1501
1502 try {
1503 close(true);
1504 } catch (Exception e) {
1505
1506
1507 }
1508 }
1509 }
1510
1511
1512 if (ioe instanceof ServerException) {
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 Throwable tt = ((ServerException)ioe).detail;
1523
1524 if (tt instanceof IOException) {
1525 throw (IOException)tt;
1526 } else if (tt instanceof RuntimeException) {
1527 throw (RuntimeException)tt;
1528 }
1529 }
1530
1531 throw ioe;
1532 }
1533
1534 public void reconnectNotificationListeners(ClientListenerInfo[] old) throws IOException {
1535 final int len = old.length;
1536 int i;
1537
1538 ClientListenerInfo[] clis = new ClientListenerInfo[len];
1539
1540 final Subject[] subjects = new Subject[len];
1541 final ObjectName[] names = new ObjectName[len];
1542 final NotificationListener[] listeners = new NotificationListener[len];
1543 final NotificationFilter[] filters = new NotificationFilter[len];
1544 final MarshalledObject<NotificationFilter>[] mFilters =
1545 Util.cast(new MarshalledObject<?>[len]);
1546 final Object[] handbacks = new Object[len];
1547
1548 for (i=0;i<len;i++) {
1549 subjects[i] = old[i].getDelegationSubject();
1550 names[i] = old[i].getObjectName();
1551 listeners[i] = old[i].getListener();
1552 filters[i] = old[i].getNotificationFilter();
1553 mFilters[i] = new MarshalledObject<NotificationFilter>(filters[i]);
1554 handbacks[i] = old[i].getHandback();
1555 }
1556
1557 try {
1558 Integer[] ids = addListenersWithSubjects(names,mFilters,subjects,false);
1559
1560 for (i=0;i<len;i++) {
1561 clis[i] = new ClientListenerInfo(ids[i],
1562 names[i],
1563 listeners[i],
1564 filters[i],
1565 handbacks[i],
1566 subjects[i]);
1567 }
1568
1569 rmiNotifClient.postReconnection(clis);
1570
1571 return;
1572 } catch (InstanceNotFoundException infe) {
1573
1574 }
1575
1576 int j = 0;
1577 for (i=0;i<len;i++) {
1578 try {
1579 Integer id = addListenerWithSubject(names[i],
1580 new MarshalledObject<NotificationFilter>(filters[i]),
1581 subjects[i],
1582 false);
1583
1584 clis[j++] = new ClientListenerInfo(id,
1585 names[i],
1586 listeners[i],
1587 filters[i],
1588 handbacks[i],
1589 subjects[i]);
1590 } catch (InstanceNotFoundException infe) {
1591 logger.warning("reconnectNotificationListeners",
1592 "Can't reconnect listener for " +
1593 names[i]);
1594 }
1595 }
1596
1597 if (j != len) {
1598 ClientListenerInfo[] tmp = clis;
1599 clis = new ClientListenerInfo[j];
1600 System.arraycopy(tmp, 0, clis, 0, j);
1601 }
1602
1603 rmiNotifClient.postReconnection(clis);
1604 }
1605
1606 protected void checkConnection() throws IOException {
1607 if (logger.debugOn())
1608 logger.debug("RMIClientCommunicatorAdmin-checkConnection",
1609 "Calling the method getDefaultDomain.");
1610
1611 connection.getDefaultDomain(null);
1612 }
1613
1614 protected void doStart() throws IOException {
1615
1616 RMIServer stub;
1617 try {
1618 stub = (rmiServer!=null)?rmiServer:
1619 findRMIServer(jmxServiceURL, env);
1620 } catch (NamingException ne) {
1621 throw new IOException("Failed to get a RMI stub: "+ne);
1622 }
1623
1624
1625 stub = connectStub(stub,env);
1626
1627
1628 Object credentials = env.get(CREDENTIALS);
1629 connection = stub.newClient(credentials);
1630
1631
1632 final ClientListenerInfo[] old = rmiNotifClient.preReconnection();
1633
1634 reconnectNotificationListeners(old);
1635
1636 connectionId = getConnectionId();
1637
1638 Notification reconnectedNotif =
1639 new JMXConnectionNotification(JMXConnectionNotification.OPENED,
1640 this,
1641 connectionId,
1642 clientNotifSeqNo++,
1643 "Reconnected to server",
1644 null);
1645 sendNotification(reconnectedNotif);
1646
1647 }
1648
1649 protected void doStop() {
1650 try {
1651 close();
1652 } catch (IOException ioe) {
1653 logger.warning("RMIClientCommunicatorAdmin-doStop",
1654 "Failed to call the method close():" + ioe);
1655 logger.debug("RMIClientCommunicatorAdmin-doStop",ioe);
1656 }
1657 }
1658 }
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706 static RMIServer connectStub(RMIServer rmiServer,
1707 Map<String, ?> environment)
1708 throws IOException {
1709 if (IIOPHelper.isStub(rmiServer)) {
1710 try {
1711 IIOPHelper.getOrb(rmiServer);
1712 } catch (UnsupportedOperationException x) {
1713
1714 IIOPHelper.connect(rmiServer, resolveOrb(environment));
1715 }
1716 }
1717 return rmiServer;
1718 }
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741 static Object resolveOrb(Map<String, ?> environment)
1742 throws IOException {
1743 if (environment != null) {
1744 final Object orb = environment.get(EnvHelp.DEFAULT_ORB);
1745 if (orb != null && !(IIOPHelper.isOrb(orb)))
1746 throw new IllegalArgumentException(EnvHelp.DEFAULT_ORB +
1747 " must be an instance of org.omg.CORBA.ORB.");
1748 if (orb != null) return orb;
1749 }
1750 final Object orb =
1751 (RMIConnector.orb==null)?null:RMIConnector.orb.get();
1752 if (orb != null) return orb;
1753
1754 final Object newOrb =
1755 IIOPHelper.createOrb((String[])null, (Properties)null);
1756 RMIConnector.orb = new WeakReference<Object>(newOrb);
1757 return newOrb;
1758 }
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771 private void readObject(java.io.ObjectInputStream s)
1772 throws IOException, ClassNotFoundException {
1773 s.defaultReadObject();
1774
1775 if (rmiServer == null && jmxServiceURL == null) throw new
1776 InvalidObjectException("rmiServer and jmxServiceURL both null");
1777
1778 initTransients();
1779 }
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812 private void writeObject(java.io.ObjectOutputStream s)
1813 throws IOException {
1814 if (rmiServer == null && jmxServiceURL == null) throw new
1815 InvalidObjectException("rmiServer and jmxServiceURL both null.");
1816 connectStub(this.rmiServer,env);
1817 s.defaultWriteObject();
1818 }
1819
1820
1821 private void initTransients() {
1822 rmbscMap = new WeakHashMap<Subject, MBeanServerConnection>();
1823 connected = false;
1824 terminated = false;
1825
1826 connectionBroadcaster = new NotificationBroadcasterSupport();
1827 }
1828
1829
1830
1831
1832
1833 private static void checkStub(Remote stub,
1834 Class<?> stubClass) {
1835
1836
1837
1838 if (stub.getClass() != stubClass) {
1839 if (!Proxy.isProxyClass(stub.getClass())) {
1840 throw new SecurityException(
1841 "Expecting a " + stubClass.getName() + " stub!");
1842 } else {
1843 InvocationHandler handler = Proxy.getInvocationHandler(stub);
1844 if (handler.getClass() != RemoteObjectInvocationHandler.class)
1845 throw new SecurityException(
1846 "Expecting a dynamic proxy instance with a " +
1847 RemoteObjectInvocationHandler.class.getName() +
1848 " invocation handler!");
1849 else
1850 stub = (Remote) handler;
1851 }
1852 }
1853
1854
1855
1856
1857 RemoteRef ref = ((RemoteObject)stub).getRef();
1858 if (ref.getClass() != UnicastRef2.class)
1859 throw new SecurityException(
1860 "Expecting a " + UnicastRef2.class.getName() +
1861 " remote reference in stub!");
1862
1863
1864
1865
1866 LiveRef liveRef = ((UnicastRef2)ref).getLiveRef();
1867 RMIClientSocketFactory csf = liveRef.getClientSocketFactory();
1868 if (csf == null || csf.getClass() != SslRMIClientSocketFactory.class)
1869 throw new SecurityException(
1870 "Expecting a " + SslRMIClientSocketFactory.class.getName() +
1871 " RMI client socket factory in stub!");
1872 }
1873
1874
1875
1876
1877
1878 private RMIServer findRMIServer(JMXServiceURL directoryURL,
1879 Map<String, Object> environment)
1880 throws NamingException, IOException {
1881 final boolean isIiop = RMIConnectorServer.isIiopURL(directoryURL,true);
1882 if (isIiop) {
1883
1884 environment.put(EnvHelp.DEFAULT_ORB,resolveOrb(environment));
1885 }
1886
1887 String path = directoryURL.getURLPath();
1888 int end = path.indexOf(';');
1889 if (end < 0) end = path.length();
1890 if (path.startsWith("/jndi/"))
1891 return findRMIServerJNDI(path.substring(6,end), environment, isIiop);
1892 else if (path.startsWith("/stub/"))
1893 return findRMIServerJRMP(path.substring(6,end), environment, isIiop);
1894 else if (path.startsWith("/ior/")) {
1895 if (!IIOPHelper.isAvailable())
1896 throw new IOException("iiop protocol not available");
1897 return findRMIServerIIOP(path.substring(5,end), environment, isIiop);
1898 } else {
1899 final String msg = "URL path must begin with /jndi/ or /stub/ " +
1900 "or /ior/: " + path;
1901 throw new MalformedURLException(msg);
1902 }
1903 }
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918 private RMIServer findRMIServerJNDI(String jndiURL, Map<String, ?> env,
1919 boolean isIiop)
1920 throws NamingException {
1921
1922 InitialContext ctx = new InitialContext(EnvHelp.mapToHashtable(env));
1923
1924 Object objref = ctx.lookup(jndiURL);
1925 ctx.close();
1926
1927 if (isIiop)
1928 return narrowIIOPServer(objref);
1929 else
1930 return narrowJRMPServer(objref);
1931 }
1932
1933 private static RMIServer narrowJRMPServer(Object objref) {
1934
1935 return (RMIServer) objref;
1936 }
1937
1938 private static RMIServer narrowIIOPServer(Object objref) {
1939 try {
1940 return IIOPHelper.narrow(objref, RMIServer.class);
1941 } catch (ClassCastException e) {
1942 if (logger.traceOn())
1943 logger.trace("narrowIIOPServer","Failed to narrow objref=" +
1944 objref + ": " + e);
1945 if (logger.debugOn()) logger.debug("narrowIIOPServer",e);
1946 return null;
1947 }
1948 }
1949
1950 private RMIServer findRMIServerIIOP(String ior, Map<String, ?> env, boolean isIiop) {
1951
1952 final Object orb = env.get(EnvHelp.DEFAULT_ORB);
1953 final Object stub = IIOPHelper.stringToObject(orb, ior);
1954 return IIOPHelper.narrow(stub, RMIServer.class);
1955 }
1956
1957 private RMIServer findRMIServerJRMP(String base64, Map<String, ?> env, boolean isIiop)
1958 throws IOException {
1959
1960 final byte[] serialized;
1961 try {
1962 serialized = base64ToByteArray(base64);
1963 } catch (IllegalArgumentException e) {
1964 throw new MalformedURLException("Bad BASE64 encoding: " +
1965 e.getMessage());
1966 }
1967 final ByteArrayInputStream bin = new ByteArrayInputStream(serialized);
1968
1969 final ClassLoader loader = EnvHelp.resolveClientClassLoader(env);
1970 final ObjectInputStream oin =
1971 (loader == null) ?
1972 new ObjectInputStream(bin) :
1973 new ObjectInputStreamWithLoader(bin, loader);
1974 final Object stub;
1975 try {
1976 stub = oin.readObject();
1977 } catch (ClassNotFoundException e) {
1978 throw new MalformedURLException("Class not found: " + e);
1979 }
1980 return (RMIServer)stub;
1981 }
1982
1983 private static final class ObjectInputStreamWithLoader
1984 extends ObjectInputStream {
1985 ObjectInputStreamWithLoader(InputStream in, ClassLoader cl)
1986 throws IOException {
1987 super(in);
1988 this.loader = cl;
1989 }
1990
1991 @Override
1992 protected Class<?> resolveClass(ObjectStreamClass classDesc)
1993 throws IOException, ClassNotFoundException {
1994 return Class.forName(classDesc.getName(), false, loader);
1995 }
1996
1997 private final ClassLoader loader;
1998 }
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065 private static final String rmiServerImplStubClassName =
2066 RMIServer.class.getName() + "Impl_Stub";
2067 private static final Class<?> rmiServerImplStubClass;
2068 private static final String rmiConnectionImplStubClassName =
2069 RMIConnection.class.getName() + "Impl_Stub";
2070 private static final Class<?> rmiConnectionImplStubClass;
2071 private static final String pRefClassName =
2072 "com.sun.jmx.remote.internal.PRef";
2073 private static final Constructor<?> proxyRefConstructor;
2074 static {
2075 final String pRefByteCodeString =
2076 "\312\376\272\276\0\0\0.\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17\0"+
2077 "\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/RemoteRef;"+
2078 ")V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/reflec"+
2079 "t/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12Exception"+
2080 "s\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1\0\40com/"+
2081 "sun/jmx/remote/internal/PRef\1\0$com/sun/jmx/remote/internal/Pr"+
2082 "oxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Ljava/rmi/serve"+
2083 "r/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0\4\0\5\0\0\0\0"+
2084 "\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261"+
2085 "\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0\6\0\0\0\17*\264\0"+
2086 "\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0\4\0\1\0\14\0\0";
2087 final byte[] pRefByteCode =
2088 NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
2089 PrivilegedExceptionAction<Constructor<?>> action =
2090 new PrivilegedExceptionAction<Constructor<?>>() {
2091 public Constructor<?> run() throws Exception {
2092 Class thisClass = RMIConnector.class;
2093 ClassLoader thisLoader = thisClass.getClassLoader();
2094 ProtectionDomain thisProtectionDomain =
2095 thisClass.getProtectionDomain();
2096 String[] otherClassNames = {ProxyRef.class.getName()};
2097 ClassLoader cl =
2098 new NoCallStackClassLoader(pRefClassName,
2099 pRefByteCode,
2100 otherClassNames,
2101 thisLoader,
2102 thisProtectionDomain);
2103 Class<?> c = cl.loadClass(pRefClassName);
2104 return c.getConstructor(RemoteRef.class);
2105 }
2106 };
2107
2108 Class<?> serverStubClass;
2109 try {
2110 serverStubClass = Class.forName(rmiServerImplStubClassName);
2111 } catch (Exception e) {
2112 logger.error("<clinit>",
2113 "Failed to instantiate " +
2114 rmiServerImplStubClassName + ": " + e);
2115 logger.debug("<clinit>",e);
2116 serverStubClass = null;
2117 }
2118 rmiServerImplStubClass = serverStubClass;
2119
2120 Class<?> stubClass;
2121 Constructor<?> constr;
2122 try {
2123 stubClass = Class.forName(rmiConnectionImplStubClassName);
2124 constr = (Constructor<?>) AccessController.doPrivileged(action);
2125 } catch (Exception e) {
2126 logger.error("<clinit>",
2127 "Failed to initialize proxy reference constructor "+
2128 "for " + rmiConnectionImplStubClassName + ": " + e);
2129 logger.debug("<clinit>",e);
2130 stubClass = null;
2131 constr = null;
2132 }
2133 rmiConnectionImplStubClass = stubClass;
2134 proxyRefConstructor = constr;
2135 }
2136
2137 private static RMIConnection shadowJrmpStub(RemoteObject stub)
2138 throws InstantiationException, IllegalAccessException,
2139 InvocationTargetException, ClassNotFoundException,
2140 NoSuchMethodException {
2141 RemoteRef ref = stub.getRef();
2142 RemoteRef proxyRef = (RemoteRef)
2143 proxyRefConstructor.newInstance(new Object[] {ref});
2144 final Constructor<?> rmiConnectionImplStubConstructor =
2145 rmiConnectionImplStubClass.getConstructor(RemoteRef.class);
2146 Object[] args = {proxyRef};
2147 RMIConnection proxyStub = (RMIConnection)
2148 rmiConnectionImplStubConstructor.newInstance(args);
2149 return proxyStub;
2150 }
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268 private static final String iiopConnectionStubClassName =
2269 "org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub";
2270 private static final String proxyStubClassName =
2271 "com.sun.jmx.remote.protocol.iiop.ProxyStub";
2272 private static final String ProxyInputStreamClassName =
2273 "com.sun.jmx.remote.protocol.iiop.ProxyInputStream";
2274 private static final String pInputStreamClassName =
2275 "com.sun.jmx.remote.protocol.iiop.PInputStream";
2276 private static final Class<?> proxyStubClass;
2277 static {
2278 final String proxyStubByteCodeString =
2279 "\312\376\272\276\0\0\0\63\0+\12\0\14\0\30\7\0\31\12\0\14\0\32\12"+
2280 "\0\2\0\33\7\0\34\12\0\5\0\35\12\0\5\0\36\12\0\5\0\37\12\0\2\0 "+
2281 "\12\0\14\0!\7\0\"\7\0#\1\0\6<init>\1\0\3()V\1\0\4Code\1\0\7_in"+
2282 "voke\1\0K(Lorg/omg/CORBA/portable/OutputStream;)Lorg/omg/CORBA"+
2283 "/portable/InputStream;\1\0\15StackMapTable\7\0\34\1\0\12Except"+
2284 "ions\7\0$\1\0\15_releaseReply\1\0'(Lorg/omg/CORBA/portable/Inp"+
2285 "utStream;)V\14\0\15\0\16\1\0-com/sun/jmx/remote/protocol/iiop/"+
2286 "PInputStream\14\0\20\0\21\14\0\15\0\27\1\0+org/omg/CORBA/porta"+
2287 "ble/ApplicationException\14\0%\0&\14\0'\0(\14\0\15\0)\14\0*\0&"+
2288 "\14\0\26\0\27\1\0*com/sun/jmx/remote/protocol/iiop/ProxyStub\1"+
2289 "\0<org/omg/stub/javax/management/remote/rmi/_RMIConnection_Stu"+
2290 "b\1\0)org/omg/CORBA/portable/RemarshalException\1\0\16getInput"+
2291 "Stream\1\0&()Lorg/omg/CORBA/portable/InputStream;\1\0\5getId\1"+
2292 "\0\24()Ljava/lang/String;\1\09(Ljava/lang/String;Lorg/omg/CORB"+
2293 "A/portable/InputStream;)V\1\0\25getProxiedInputStream\0!\0\13\0"+
2294 "\14\0\0\0\0\0\3\0\1\0\15\0\16\0\1\0\17\0\0\0\21\0\1\0\1\0\0\0\5"+
2295 "*\267\0\1\261\0\0\0\0\0\1\0\20\0\21\0\2\0\17\0\0\0G\0\4\0\4\0\0"+
2296 "\0'\273\0\2Y*+\267\0\3\267\0\4\260M\273\0\2Y,\266\0\6\267\0\4N"+
2297 "\273\0\5Y,\266\0\7-\267\0\10\277\0\1\0\0\0\14\0\15\0\5\0\1\0\22"+
2298 "\0\0\0\6\0\1M\7\0\23\0\24\0\0\0\6\0\2\0\5\0\25\0\1\0\26\0\27\0"+
2299 "\1\0\17\0\0\0'\0\2\0\2\0\0\0\22+\306\0\13+\300\0\2\266\0\11L*+"+
2300 "\267\0\12\261\0\0\0\1\0\22\0\0\0\3\0\1\14\0\0";
2301 final String pInputStreamByteCodeString =
2302 "\312\376\272\276\0\0\0\63\0\36\12\0\7\0\17\11\0\6\0\20\12\0\21"+
2303 "\0\22\12\0\6\0\23\12\0\24\0\25\7\0\26\7\0\27\1\0\6<init>\1\0'("+
2304 "Lorg/omg/CORBA/portable/InputStream;)V\1\0\4Code\1\0\10read_an"+
2305 "y\1\0\25()Lorg/omg/CORBA/Any;\1\0\12read_value\1\0)(Ljava/lang"+
2306 "/Class;)Ljava/io/Serializable;\14\0\10\0\11\14\0\30\0\31\7\0\32"+
2307 "\14\0\13\0\14\14\0\33\0\34\7\0\35\14\0\15\0\16\1\0-com/sun/jmx"+
2308 "/remote/protocol/iiop/PInputStream\1\0\61com/sun/jmx/remote/pr"+
2309 "otocol/iiop/ProxyInputStream\1\0\2in\1\0$Lorg/omg/CORBA/portab"+
2310 "le/InputStream;\1\0\"org/omg/CORBA/portable/InputStream\1\0\6n"+
2311 "arrow\1\0*()Lorg/omg/CORBA_2_3/portable/InputStream;\1\0&org/o"+
2312 "mg/CORBA_2_3/portable/InputStream\0!\0\6\0\7\0\0\0\0\0\3\0\1\0"+
2313 "\10\0\11\0\1\0\12\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261\0\0\0"+
2314 "\0\0\1\0\13\0\14\0\1\0\12\0\0\0\24\0\1\0\1\0\0\0\10*\264\0\2\266"+
2315 "\0\3\260\0\0\0\0\0\1\0\15\0\16\0\1\0\12\0\0\0\25\0\2\0\2\0\0\0"+
2316 "\11*\266\0\4+\266\0\5\260\0\0\0\0\0\0";
2317 final byte[] proxyStubByteCode =
2318 NoCallStackClassLoader.stringToBytes(proxyStubByteCodeString);
2319 final byte[] pInputStreamByteCode =
2320 NoCallStackClassLoader.stringToBytes(pInputStreamByteCodeString);
2321 final String[] classNames={proxyStubClassName, pInputStreamClassName};
2322 final byte[][] byteCodes = {proxyStubByteCode, pInputStreamByteCode};
2323 final String[] otherClassNames = {
2324 iiopConnectionStubClassName,
2325 ProxyInputStreamClassName,
2326 };
2327 if (IIOPHelper.isAvailable()) {
2328 PrivilegedExceptionAction<Class<?>> action =
2329 new PrivilegedExceptionAction<Class<?>>() {
2330 public Class<?> run() throws Exception {
2331 Class thisClass = RMIConnector.class;
2332 ClassLoader thisLoader = thisClass.getClassLoader();
2333 ProtectionDomain thisProtectionDomain =
2334 thisClass.getProtectionDomain();
2335 ClassLoader cl =
2336 new NoCallStackClassLoader(classNames,
2337 byteCodes,
2338 otherClassNames,
2339 thisLoader,
2340 thisProtectionDomain);
2341 return cl.loadClass(proxyStubClassName);
2342 }
2343 };
2344 Class<?> stubClass;
2345 try {
2346 stubClass = AccessController.doPrivileged(action);
2347 } catch (Exception e) {
2348 logger.error("<clinit>",
2349 "Unexpected exception making shadow IIOP stub class: "+e);
2350 logger.debug("<clinit>",e);
2351 stubClass = null;
2352 }
2353 proxyStubClass = stubClass;
2354 } else {
2355 proxyStubClass = null;
2356 }
2357 }
2358
2359 private static RMIConnection shadowIiopStub(Object stub)
2360 throws InstantiationException, IllegalAccessException {
2361 Object proxyStub = proxyStubClass.newInstance();
2362 IIOPHelper.setDelegate(proxyStub, IIOPHelper.getDelegate(stub));
2363 return (RMIConnection) proxyStub;
2364 }
2365
2366 private static RMIConnection getConnection(RMIServer server,
2367 Object credentials,
2368 boolean checkStub)
2369 throws IOException {
2370 RMIConnection c = server.newClient(credentials);
2371 if (checkStub) checkStub(c, rmiConnectionImplStubClass);
2372 try {
2373 if (c.getClass() == rmiConnectionImplStubClass)
2374 return shadowJrmpStub((RemoteObject) c);
2375 if (c.getClass().getName().equals(iiopConnectionStubClassName))
2376 return shadowIiopStub(c);
2377 logger.trace("getConnection",
2378 "Did not wrap " + c.getClass() + " to foil " +
2379 "stack search for classes: class loading semantics " +
2380 "may be incorrect");
2381 } catch (Exception e) {
2382 logger.error("getConnection",
2383 "Could not wrap " + c.getClass() + " to foil " +
2384 "stack search for classes: class loading semantics " +
2385 "may be incorrect: " + e);
2386 logger.debug("getConnection",e);
2387
2388
2389 }
2390 return c;
2391 }
2392
2393 private static byte[] base64ToByteArray(String s) {
2394 int sLen = s.length();
2395 int numGroups = sLen/4;
2396 if (4*numGroups != sLen)
2397 throw new IllegalArgumentException(
2398 "String length must be a multiple of four.");
2399 int missingBytesInLastGroup = 0;
2400 int numFullGroups = numGroups;
2401 if (sLen != 0) {
2402 if (s.charAt(sLen-1) == '=') {
2403 missingBytesInLastGroup++;
2404 numFullGroups--;
2405 }
2406 if (s.charAt(sLen-2) == '=')
2407 missingBytesInLastGroup++;
2408 }
2409 byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
2410
2411
2412 int inCursor = 0, outCursor = 0;
2413 for (int i=0; i<numFullGroups; i++) {
2414 int ch0 = base64toInt(s.charAt(inCursor++));
2415 int ch1 = base64toInt(s.charAt(inCursor++));
2416 int ch2 = base64toInt(s.charAt(inCursor++));
2417 int ch3 = base64toInt(s.charAt(inCursor++));
2418 result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
2419 result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
2420 result[outCursor++] = (byte) ((ch2 << 6) | ch3);
2421 }
2422
2423
2424 if (missingBytesInLastGroup != 0) {
2425 int ch0 = base64toInt(s.charAt(inCursor++));
2426 int ch1 = base64toInt(s.charAt(inCursor++));
2427 result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
2428
2429 if (missingBytesInLastGroup == 1) {
2430 int ch2 = base64toInt(s.charAt(inCursor++));
2431 result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
2432 }
2433 }
2434
2435
2436 return result;
2437 }
2438
2439
2440
2441
2442
2443
2444
2445
2446 private static int base64toInt(char c) {
2447 int result;
2448
2449 if (c >= base64ToInt.length)
2450 result = -1;
2451 else
2452 result = base64ToInt[c];
2453
2454 if (result < 0)
2455 throw new IllegalArgumentException("Illegal character " + c);
2456 return result;
2457 }
2458
2459
2460
2461
2462
2463
2464
2465
2466 private static final byte base64ToInt[] = {
2467 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2468 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2469 -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
2470 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
2471 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2472 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
2473 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
2474 };
2475
2476
2477
2478
2479 private ClassLoader pushDefaultClassLoader() {
2480 final Thread t = Thread.currentThread();
2481 final ClassLoader old = t.getContextClassLoader();
2482 if (defaultClassLoader != null)
2483 AccessController.doPrivileged(new PrivilegedAction<Void>() {
2484 public Void run() {
2485 t.setContextClassLoader(defaultClassLoader);
2486 return null;
2487 }
2488 });
2489 return old;
2490 }
2491
2492 private void popDefaultClassLoader(final ClassLoader old) {
2493 AccessController.doPrivileged(new PrivilegedAction<Void>() {
2494 public Void run() {
2495 Thread.currentThread().setContextClassLoader(old);
2496 return null;
2497 }
2498 });
2499 }
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515 private final RMIServer rmiServer;
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526 private final JMXServiceURL jmxServiceURL;
2527
2528
2529
2530
2531
2532
2533 private transient Map<String, Object> env;
2534 private transient ClassLoader defaultClassLoader;
2535 private transient RMIConnection connection;
2536 private transient String connectionId;
2537
2538 private transient long clientNotifSeqNo = 0;
2539
2540 private transient WeakHashMap<Subject, MBeanServerConnection> rmbscMap;
2541
2542 private transient RMINotifClient rmiNotifClient;
2543
2544
2545 private transient long clientNotifCounter = 0;
2546
2547 private transient boolean connected;
2548
2549 private transient boolean terminated;
2550
2551
2552 private transient Exception closeException;
2553
2554 private transient NotificationBroadcasterSupport connectionBroadcaster;
2555
2556 private transient ClientCommunicatorAdmin communicatorAdmin;
2557
2558
2559
2560
2561
2562 private static volatile WeakReference<Object> orb = null;
2563
2564
2565
2566 private static String objects(final Object[] objs) {
2567 if (objs == null)
2568 return "null";
2569 else
2570 return Arrays.asList(objs).toString();
2571 }
2572
2573 private static String strings(final String[] strs) {
2574 return objects(strs);
2575 }
2576 }